/**
 * @author Vitor Franco do Carmo (vitor.carmo@capgemini.com)
 * @since 25/05/2012
 *
 */
package br.com.vfcfw.controller.converter;

import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.FacesConverter;

import org.apache.log4j.Logger;

import br.com.vfcfw.commons.util.LogUtil;
import br.com.vfcfw.commons.util.ReflexaoUtil;

/**
 * Converter para entidades mapeadas com JPA. Baseia-se na anotação @Id para identificar o atributo que representa a
 * identidade da entidade.
 * 
 * @author Vitor Franco do Carmo (vitor.carmo@capgemini.com)
 * @since 25/05/2012
 * 
 */
@FacesConverter(value = "converter.entityConverter")
@ManagedBean(name = "entityConverter", eager = true)
@ApplicationScoped
public class EntityConverter extends BaseConverter {

    private static final Logger LOG = Logger.getLogger(EntityConverter.class.getSimpleName());

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public Object getAsObject(FacesContext ctx, UIComponent component, String value) {

        if (possuiValor(value)) {
            return component.getAttributes().get(value);
        }

        return null;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public String getAsString(FacesContext ctx, UIComponent component, Object obj) {

        if (possuiValor(obj)) {

            String id;

            try {
                id = this.getId(obj.getClass(), obj);

                if (id == null) {
                    id = "";
                }

                id = id.trim();
                component.getAttributes().put(id, obj);

                return id;
            } catch (Exception e) {
                LogUtil.error(LOG, e.getMessage());
            }
        }

        return null;
    }

    /**
     * Retorna ao id da entidade.
     * 
     * @param classe Classe da entidade.
     * @param obj Entidade.
     * @return ID da entidade.
     * @throws Exception
     */
    public String getId(Class<?> classe, Object obj) throws Exception {

        Object valor = ReflexaoUtil.obterValorCampoId(classe, obj);

        return classe.toString() + ((valor != null) ? valor.toString() : null);
    }
}